package com.shux.springsource;

import java.io.IOException;
import java.util.Date;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.io.ClassPathResource;

import com.shux.springsource.bean.AutowireBeanA;
import com.shux.springsource.bean.BeanA;
import com.shux.springsource.bean.BeanB;
import com.shux.springsource.bean.BeanC;
import com.shux.springsource.bean.CircleBeanA;
import com.shux.springsource.bean.CircleBeanB;
import com.shux.springsource.bean.PropertyEditorBean;
import com.shux.springsource.bean.PropertyPlaceholderBean;
import com.shux.springsource.beanfactory.MyBeanFactory;
import com.shux.springsource.beanfactory.User;
import com.shux.springsource.beanpost.MyBeanPostProcessor;
import com.shux.springsource.beanpost.MyInstantiationAwareBeanPostProcessor;
import com.shux.springsource.beanpost.MyInstantiationAwareBeanPostProcessorAdapter;
import com.shux.springsource.beanpost.SensitivePropertyRemovingBeanFactoryPostProcessor;
import com.shux.springsource.biz.IMyBeanBiz;
import com.shux.springsource.biz.impl.MyBeanBizImpl;
import com.shux.springsource.customtag.ServiceBean;
import com.shux.springsource.depends.on.DependentBean;
import com.shux.springsource.event.MessageEvent;
import com.shux.springsource.listener.MessageEventListener;
import com.shux.springsource.lookup.HelloApi;

/**
 * Hello world!
 *
 */
public class App 
{
    @Test
    public void testCustomTag() {
    	ApplicationContext context = new ClassPathXmlApplicationContext("customBean.xml");
    	ServiceBean bean = context.getBean("customtag", ServiceBean.class);
    	System.out.println(bean.getInterfaces());
    }
    @Test
    public void testCustomTag2() {
    	BeanFactory factory = new XmlBeanFactory(new ClassPathResource("customBean.xml"));
    	ServiceBean bean = factory.getBean("customtag", ServiceBean.class);
    	System.out.println(bean.getInterfaces());
    	System.out.println(bean.getRef());
    }
    
    @Test
    public void testSpringTag() {
    	BeanFactory factory = new XmlBeanFactory(new ClassPathResource("mybeans.xml"));
        IMyBeanBiz mybeanbiz = factory.getBean("mybean", MyBeanBizImpl.class);
        mybeanbiz.printName("simba");
    }
    
    @Test
    public void testMyfactoryBean() throws Exception {
    	BeanFactory factory = new XmlBeanFactory(new ClassPathResource("mybeans.xml"));
    	User mybeanbiz = factory.getBean("myfactorybean", User.class);
        mybeanbiz.printUsername("simba");
        System.out.println("-------------------------");
        MyBeanFactory mybeanFactory = factory.getBean("&myfactorybean", MyBeanFactory.class);
        mybeanFactory.getObject();
    }
    
    @Test
    public void testPostBeanProcessor() {
    	ConfigurableBeanFactory factory = new XmlBeanFactory(new ClassPathResource("mybeans.xml"));
    	
    	factory.addBeanPostProcessor(new MyBeanPostProcessor());
    	factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
    	factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorAdapter());
    	//factory.addBeanPostProcessor(new MyBeanFactoryPostProcessor());
    	User user = factory.getBean("userBean",User.class);
    	user.printUsername("simba");
    	System.out.println(user.getPhone());
    }
    	/**
         * 构造方法依赖
         */
        @Test
        public void testConstructCircleDepence() {
        	ApplicationContext cxf = new ClassPathXmlApplicationContext("mybeans.xml");
        	BeanA beana = cxf.getBean("beana", BeanA.class);
        	beana.printBeanA();
        	BeanB beanb = cxf.getBean("beanb", BeanB.class);
        	beanb.printBeanB();
        	BeanC beanc = cxf.getBean("beanc", BeanC.class);
        	beanc.printBeanC();
       }
    @Test
    public void testDependsOn() {
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	context.registerShutdownHook();
    	DependentBean dependentBean = context.getBean("dependentBean",DependentBean.class);
    	try {
			dependentBean.write("hello,我正在写入\r\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    @Test
    public void testLookUp() {
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	System.out.println("------------Singleton sayHello-----------");
    	HelloApi singletonHelloApi = context.getBean("singletonHelloApi", HelloApi.class);
    	singletonHelloApi.sayHello();
    	singletonHelloApi = context.getBean("singletonHelloApi", HelloApi.class);
    	singletonHelloApi.sayHello();
    	System.out.println("------------Prototype sayHello-----------");
    	HelloApi prototypeHelloApi = context.getBean("prototypeHelloApi", HelloApi.class);
    	prototypeHelloApi.sayHello();
    	prototypeHelloApi = context.getBean("prototypeHelloApi", HelloApi.class);
    	prototypeHelloApi.sayHello();
    }
    
    /**
     * 构造方法依赖
     */
    @Test
    public void testSetterCircleDepence() {
    	ApplicationContext cxf = new ClassPathXmlApplicationContext("mybeans.xml");
    	CircleBeanA beana = cxf.getBean("circleBeana", CircleBeanA.class);
    	beana.printBeanA();
    	CircleBeanB beanb = cxf.getBean("circleBeanb", CircleBeanB.class);
    	//beanb.printBeanB();
    	/*CircleBeanC beanc = cxf.getBean("circleBeanc", CircleBeanC.class);
    	beanc.printBeanC();*/
   }
    @Test
    public void testAutowired() {
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	AutowireBeanA beana = context.getBean(AutowireBeanA.class);
    	beana.print();
    }
    
    @Test
    public void testPropertyEditor() {
    	ApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	PropertyEditorBean propertyEditorBean = context.getBean("propertyEditorBean", PropertyEditorBean.class);
    	System.out.println(propertyEditorBean);
    }
    @Test
    public void testBeanFactoryPostProcessor() {
    	ConfigurableListableBeanFactory factory = new XmlBeanFactory(new ClassPathResource("mybeans.xml"));
    	SensitivePropertyRemovingBeanFactoryPostProcessor processor = factory.getBean("postProcessor",SensitivePropertyRemovingBeanFactoryPostProcessor.class);
    	processor.postProcessBeanFactory(factory);
    	System.out.println(factory.getBean("postProcessorBean"));
    }
    @Test
    public void testMessageEventListener() {
    	ApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	MessageEventListener listener = context.getBean("messageEventListener",MessageEventListener.class);
    	context.publishEvent(new MessageEvent("hello","world"));
    }
    @Test
    public void testPropertyPlaceholderConfigurer() throws IOException {
    	ApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	//context.getResource(location)
    	/*Resource resource = context.getResource("conf/system.properties");
    	InputStreamReader reader = new InputStreamReader(resource.getInputStream());
    	BufferedReader br = new BufferedReader(reader);
    	String line = null;
    	while ((line = br.readLine()) != null) {
    		System.out.println(line);
    	}*/
    	PropertyPlaceholderBean bean = context.getBean(PropertyPlaceholderBean.class);
    	System.out.println(bean.getMessage());
    }
    @Test
    public void testConverter() {
/*//    	DefaultConversionService conversionService = new DefaultConversionService();
//    	conversionService.addConverter(new StringToDateCoverter());
//    	Date bean = conversionService.convert("2018-02-07 13:25:52", Date.class);
//    	System.out.println(bean);
*/    	
    	ApplicationContext context = new ClassPathXmlApplicationContext("mybeans.xml");
    	ConversionServiceFactoryBean conversionService = context.getBean("&conversionService", ConversionServiceFactoryBean.class);
    	ConversionService service = conversionService.getObject();
    	Date date = service.convert("2018-02-07 13:25:52", Date.class);
    	System.out.println(date);
    }
    
}
